import { Material, Mesh, OrthographicCamera, Scene, Vector3 } from "three";
import { Image } from "zrender";
import { CqkjMap } from "../Basic/CqkjMap";
import { MapElement, MapElementOption } from "../Basic/MapElement";
import { antiShake, setValue } from "../Util/common";
import { render } from "../Util/renderer";
import { UNITSQUARE } from "../Util/static";

export interface GroundIsosurfaceOption extends MapElementOption {
  material: Material
}

export class GroundIsosurface extends MapElement<GroundIsosurfaceOption>{
  private readonly _scene = new Scene()
  private readonly _camera = new OrthographicCamera(-1, 1, 1, -1, 0.1, 100)
  private readonly _canvas = document.createElement('canvas')
  private readonly _image = new Image({
    scaleY: -1,
    z: 10
  })
  key = new Vector3()
  get show(): boolean {
    return this.option.show
  }
  set show(val: boolean) {
    setValue(this.option,'show',val,()=>{
      val?this._image.show():this._image.hide()
    })
  }

  constructor(map: CqkjMap, option: GroundIsosurfaceOption) {
    super(map, option)
    this.reflesh=antiShake(this.reflesh.bind(this))
    const { _scene, _image, _canvas, _camera } = this
    _canvas.width = 4096
    _canvas.height = 4096
    const mesh = new Mesh(UNITSQUARE, option.material)
    mesh.scale.set(5000000, 5000000, 1)
    _scene.add(mesh)
    _camera.position.set(0, 0, 10)
    _camera.lookAt(this._scene.position)
    map.ground.root.add(_image)
    map.show && this.onAfterViewChange()
  }

  onAfterViewChange(): void {
    const { map, _image, _camera, _scene, _canvas } = this
    const { key, box } = map.ground
    if (!this.key.equals(key)) {
      this.key.copy(key)
      _camera.left = box.min.x
      _camera.right = box.max.x
      _camera.top = box.max.y
      _camera.bottom = box.min.y
      _camera.updateProjectionMatrix()
      render(_scene, _camera, _canvas)
      _image.attr({
        x: box.min.x,
        y: box.max.y,
        style: {
          image: _canvas,
          width: box.max.x - box.min.x,
          height: box.max.y - box.min.y,
        }
      })
    }
  }

  reflesh() {
    const { _image, _camera, _scene, _canvas } = this
    render(_scene, _camera, _canvas)
    _image.attr({
      style: {
        image: _canvas,

      }
    })
  }

  onDestroy(): void {
    throw new Error("Method not implemented.");
  }

}